package cn.zf233.xcloud.service.impl;

import cn.zf233.xcloud.config.common.ElasticSearchConfig;
import cn.zf233.xcloud.config.common.RabbitMQConfig;
import cn.zf233.xcloud.entity.File;
import cn.zf233.xcloud.service.receive.IRabbitMQMessageSend;
import com.rabbitmq.client.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Map;

/**
 * Created by zf233 on 2021/6/4
 * RabbitMQ 配合 ElasticSearch 的搜索服务
 */
@Service
@ConditionalOnBean({RabbitMQConfig.class, ElasticSearchConfig.class})
public class SearchEnhanceService extends SearchDefaultServiceImpl {

    private final Logger logger = LoggerFactory.getLogger(SearchEnhanceService.class);

    @Autowired
    private IRabbitMQMessageSend rabbitMQMessageSend;

    @Override
    public void insertOrUpdateOne(File file) {
        rabbitMQMessageSend.sendMessageOfESInsertOrUpdateToRabbitMQ(file);
    }

    @Override
    public void deleteOne(File file) {
        rabbitMQMessageSend.sendMessageOfEsRemoveToRabbitMQ(file);
    }


    @RabbitListener(queues = RabbitMQConfig.TOPIC_QUEUE_INSERT_OR_UPDATE_OF_ES)
    @RabbitHandler
    public void topicReceiveInsertOrUpdate(@Payload File message, Channel channel, @Headers Map<String, Object> headers) throws Exception {
        this.logger.info(" **** RABBIT MQ **** PRODUCE IN OR UP START -------------> ");
        if (message != null) {
            long deliveryTag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);
            try {
                //手工ack
                super.insertOrUpdateOne(message);
                channel.basicAck(deliveryTag, false);
                this.logger.info(" **** RABBIT MQ **** PRODUCE BASICACK TRUE --------------> ");
            } catch (Exception e) {
                this.logger.error(" **** RABBIT MQ **** EXCEPTION PRODUCE IN OR UP FAIL ----> ");
                try {
                    channel.basicReject(deliveryTag, true);
                    this.logger.info(" **** RABBIT MQ **** PRODUCE BASIC REJECT SUCCESS -------> ");
                } catch (IOException ioException) {
                    ioException.printStackTrace();
                    this.logger.error(" **** RABBIT MQ **** EXCEPTION PRODUCE BASICNACK FAIL ---> ");
                }
                throw e;
            }
        }
        this.logger.info(" **** RABBIT MQ **** PRODUCE IN OR UP END ---------------> ");
    }

    @RabbitListener(queues = RabbitMQConfig.TOPIC_QUEUE_REMOVE_OF_ES)
    @RabbitHandler
    public void topicReceiveRemove(@Payload File message, Channel channel, @Headers Map<String, Object> headers) throws Exception {
        this.logger.info(" **** RABBIT MQ ****  PRODUCE REMOVE START --------------> ");
        if (message != null) {
            long deliveryTag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);
            try {
                //手工ack
                super.deleteOne(message);
                channel.basicAck(deliveryTag, false);
                this.logger.info(" **** RABBIT MQ **** PRODUCE BASICACK TRUE --------------> ");
            } catch (Exception e) {
                this.logger.error(" **** RABBIT MQ **** EXCEPTION PRODUCE REMOVE FAIL ------> ");
                try {
                    channel.basicReject(deliveryTag, true);
                    this.logger.info(" **** RABBIT MQ **** PRODUCE BASIC REJECT SUCCESS -------> ");
                } catch (IOException ioException) {
                    ioException.printStackTrace();
                    this.logger.error(" **** RABBIT MQ **** EXCEPTION PRODUCE BASICNACK FAIL ---> ");
                }
                throw e;
            }
        }
        this.logger.info(" **** RABBIT MQ ****  PRODUCE REMOVE END ----------------> ");
    }
}